/**
 * @file ice_cream_process.c
 * @brief 冰淇淋制作流程实现（支持重复选择多种果酱和顶料，包含出杯统计功能）
 */
#include "ice_cream_process.h"
#include "ice_cream_control.h"
#include "ice_cream_driver.h"

#include "state_machine.h"
#include <stdio.h>
#include <string.h>
#include <time.h> // 用于时间戳相关函数

// 静态全局变量
static ice_cream_process_data_t process_data;
static bool save_statistics(void);
// 状态处理函数声明
static void process_idle_enter(void);
static void process_idle_process(void);
static void process_idle_exit(void);

static void process_init_enter(void);
static void process_init_process(void);
static void process_init_exit(void);

static void process_homing_enter(void);
static void process_homing_process(void);
static void process_homing_exit(void);

static void process_drop_cup_enter(void);
static void process_drop_cup_process(void);
static void process_drop_cup_exit(void);

static void process_move_to_milk_enter(void);
static void process_move_to_milk_process(void);
static void process_move_to_milk_exit(void);

static void process_fill_milk_enter(void);
static void process_fill_milk_process(void);
static void process_fill_milk_exit(void);

static void process_milk_delay_enter(void);
static void process_milk_delay_process(void);
static void process_milk_delay_exit(void);

static void process_move_to_jam_enter(void);
static void process_move_to_jam_process(void);
static void process_move_to_jam_exit(void);

static void process_add_jam_enter(void);
static void process_add_jam_process(void);
static void process_add_jam_exit(void);

static void process_jam_delay_enter(void);
static void process_jam_delay_process(void);
static void process_jam_delay_exit(void);

static void process_move_to_topping_enter(void);
static void process_move_to_topping_process(void);
static void process_move_to_topping_exit(void);

static void process_add_topping_enter(void);
static void process_add_topping_process(void);
static void process_add_topping_exit(void);

static void process_topping_delay_enter(void);
static void process_topping_delay_process(void);
static void process_topping_delay_exit(void);

static void process_move_to_dispense_enter(void);
static void process_move_to_dispense_process(void);
static void process_move_to_dispense_exit(void);

static void process_open_door_enter(void);
static void process_open_door_process(void);
static void process_open_door_exit(void);

static void process_wait_takeaway_enter(void);
static void process_wait_takeaway_process(void);
static void process_wait_takeaway_exit(void);

static void process_close_door_enter(void);
static void process_close_door_process(void);
static void process_close_door_exit(void);

static void process_complete_enter(void);
static void process_complete_process(void);
static void process_complete_exit(void);

static void process_error_enter(void);
static void process_error_process(void);
static void process_error_exit(void);

// 辅助函数声明
static uint32_t get_beijing_timestamp(void);
static void update_cup_statistics(void);
static void update_jam_statistics(uint8_t jam_type);
static void update_topping_statistics(uint8_t topping_type);

// 常量状态表
static const StateDef process_states[PROCESS_STATE_COUNT] = {
    DEFINE_STATE(PROCESS_IDLE, process_idle_enter, process_idle_process, process_idle_exit),
    DEFINE_STATE(PROCESS_INIT, process_init_enter, process_init_process, process_init_exit),
    DEFINE_STATE(PROCESS_HOMING, process_homing_enter, process_homing_process, process_homing_exit),
    DEFINE_STATE(PROCESS_DROP_CUP, process_drop_cup_enter, process_drop_cup_process, process_drop_cup_exit),
    DEFINE_STATE(PROCESS_MOVE_TO_MILK, process_move_to_milk_enter, process_move_to_milk_process, process_move_to_milk_exit),
    DEFINE_STATE(PROCESS_FILL_MILK, process_fill_milk_enter, process_fill_milk_process, process_fill_milk_exit),
    DEFINE_STATE(PROCESS_MILK_DELAY, process_milk_delay_enter, process_milk_delay_process, process_milk_delay_exit),
    DEFINE_STATE(PROCESS_MOVE_TO_JAM, process_move_to_jam_enter, process_move_to_jam_process, process_move_to_jam_exit),
    DEFINE_STATE(PROCESS_ADD_JAM, process_add_jam_enter, process_add_jam_process, process_add_jam_exit),
    DEFINE_STATE(PROCESS_JAM_DELAY, process_jam_delay_enter, process_jam_delay_process, process_jam_delay_exit),
    DEFINE_STATE(PROCESS_MOVE_TO_TOPPING, process_move_to_topping_enter, process_move_to_topping_process, process_move_to_topping_exit),
    DEFINE_STATE(PROCESS_ADD_TOPPING, process_add_topping_enter, process_add_topping_process, process_add_topping_exit),
    DEFINE_STATE(PROCESS_TOPPING_DELAY, process_topping_delay_enter, process_topping_delay_process, process_topping_delay_exit),
    DEFINE_STATE(PROCESS_MOVE_TO_DISPENSE, process_move_to_dispense_enter, process_move_to_dispense_process, process_move_to_dispense_exit),
    DEFINE_STATE(PROCESS_OPEN_DOOR, process_open_door_enter, process_open_door_process, process_open_door_exit),
    DEFINE_STATE(PROCESS_WAIT_TAKEAWAY, process_wait_takeaway_enter, process_wait_takeaway_process, process_wait_takeaway_exit),
    DEFINE_STATE(PROCESS_CLOSE_DOOR, process_close_door_enter, process_close_door_process, process_close_door_exit),
    DEFINE_STATE(PROCESS_COMPLETE, process_complete_enter, process_complete_process, process_complete_exit),
    DEFINE_STATE(PROCESS_ERROR, process_error_enter, process_error_process, process_error_exit)};

// 状态迁移函数
static void transition_to(ProcessState target)
{
    // process_data.fsm.target_state = target;
    printf("Transitioning to state %d\n", target);
    state_machine_set_target(&process_data.fsm, target);
}

// 错误处理函数

const char *error_code_to_string(ErrorCode error)
{

    switch (error)
    {
    case ERROR_NONE:
        return "No error";
    case ERROR_HOMING_FAILED:
        return "Homing failed";
    case ERROR_CUP_NOT_DETECTED:
        return "Cup not detected";
    case ERROR_AXIS_MOVE_TIMEOUT:
        return "Axis move timeout";
    case ERROR_MILK_DISPENSE_FAILED:
        return "Milk dispense failed";
    case ERROR_JAM_DISPENSE_FAILED:
        return "Jam dispense failed";
    case ERROR_TOPPING_DISPENSE_FAILED:
        return "Topping dispense failed";
    case ERROR_JAM_TYPE_INVALID:
        return "Jam type invalid";
    case ERROR_TOPPING_TYPE_INVALID:
        return "Topping type invalid";
    case ERROR_DOOR_CONTROL_FAILED:
        return "Door control failed";
    }
}

static void set_error(ErrorCode error)
{
    process_data.error_code = error;
    printf("Error: %s\n", error_code_to_string(error));
    transition_to(PROCESS_ERROR);
}

// 获取北京时间戳（UTC+8）
static uint32_t get_beijing_timestamp(void)
{
    time_t utc_time;
    struct tm *local_tm;

    // 获取当前UTC时间
    time(&utc_time);

    // 转换为北京时间（UTC+8）
    return utc_time + BEIJING_TIMEZONE_OFFSET * 3600;
}

// 更新出杯统计信息
static void update_cup_statistics(void)
{
    // 根据出杯数为0时记住第一次出杯起始时间
    if (process_data.stats.total_cups.count == 0)
    {
        process_data.stats.total_cups.start_time = get_beijing_timestamp();
    }

    process_data.stats.total_cups.count++;
    process_data.last_cup_timestamp = get_beijing_timestamp();
    printf("出杯统计更新: 总杯数=%d, 最后出杯时间=%lu\n",
           process_data.stats.total_cups.count,
           process_data.last_cup_timestamp);

    // 统计数据更新
    process_data.statistics_updated = 1;
}

// 更新果酱使用统计
static void update_jam_statistics(uint8_t jam_type)
{
    if (jam_type < 3)
    { // 确保不越界
        // 根据出杯数为0时记住第一次出杯起始时间
        if (process_data.stats.jam[jam_type].count == 0)
        {
            process_data.stats.jam[jam_type].start_time = get_beijing_timestamp();
        }
        process_data.stats.jam[jam_type].count++;
        printf("果酱%d使用统计更新: 总次数=%d\n",
               jam_type + 1, process_data.stats.jam[jam_type].count);
        process_data.statistics_updated = 1;
    }
}

// 更新顶料使用统计
static void update_topping_statistics(uint8_t topping_type)
{
    if (topping_type < 3)
    { // 确保不越界
        // 根据出杯数为0时记住第一次出杯起始时间
        if (process_data.stats.topping[topping_type].count == 0)
        {
            process_data.stats.topping[topping_type].start_time = system_get_time_ms();
        }
        process_data.stats.topping[topping_type].count++;
        printf("顶料%d使用统计更新: 总次数=%d\n",
               topping_type + 1, process_data.stats.topping[topping_type].count);
        process_data.statistics_updated = 1;
    }
}

// 空闲状态
static void process_idle_enter(void)
{
    printf("进入空闲状态\n");
    process_data.timer = 0;
    process_data.error_code = ERROR_NONE;
    // 清空选择列表
    process_data.selected_jam_count = 0;
    process_data.selected_topping_count = 0;
}

static void process_idle_process(void)
{
    // 等待启动指令
}

static void process_idle_exit(void)
{
    printf("离开空闲状态\n");
}

// 初始化状态
static void process_init_enter(void)
{
    printf("进入初始化状态\n");
    process_data.timer = system_get_time_ms();
}

static void process_init_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 初始化超时检查（5秒）
    if (elapsed > 5000)
    {
        set_error(ERROR_HOMING_FAILED);
        return;
    }

    // 初始化完成，进入原点回归

    transition_to(PROCESS_HOMING);
}

static void process_init_exit(void)
{
    printf("初始化状态完成\n");
}

// 原点回归状态
static void process_homing_enter(void)
{
    printf("进入原点回归状态\n");
    process_data.timer = system_get_time_ms();
    axis_xz_homing();
}

static void process_homing_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 原点回归超时检查（10秒）
    if (elapsed > 10000)
    {
        set_error(ERROR_HOMING_FAILED);
        return;
    }

    // 原点回归完成，进入落杯状态
    if (axis_xz_is_homed())
    {
        transition_to(PROCESS_DROP_CUP);
    }
}

static void process_homing_exit(void)
{
    printf("原点回归完成\n");
}

// 落杯状态
static void process_drop_cup_enter(void)
{
    printf("进入落杯状态\n");
    process_data.timer = system_get_time_ms();

    // 移动到取杯位置
    if (!axis_xz_move_to(process_data.config.cup_drop_pos))
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }
}

static void process_drop_cup_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 移动超时检查（5秒）
    if (elapsed > 5000)
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }

    // 位置到达后执行落杯
    if (axis_xz_is_moving())
    {
        return;
    }
   

    if(cup_drop())
    {
        process_data.timer = system_get_time_ms();
         printf("开始落杯\n");
         return;
    }
    else if (elapsed>4000)
    {
       set_error(ERROR_CUP_NOT_DETECTED);
    }

    if (cup_is_present())
    {
        transition_to(PROCESS_MOVE_TO_MILK);
    }

}

static void process_drop_cup_exit(void)
{
    printf("落杯完成\n");
}

// 移动到奶浆位置
static void process_move_to_milk_enter(void)
{
    printf("进入移动到奶浆位置状态\n");
    process_data.timer = system_get_time_ms();

    // 移动到奶浆加注位置
    if (!axis_xz_move_to(process_data.config.milk.fill_pos))
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }
}

static void process_move_to_milk_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 移动超时检查（5秒）
    if (elapsed > 5000)
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }

    // 移动完成，进入奶浆加注
    if (!axis_xz_is_moving())
    {
        transition_to(PROCESS_FILL_MILK);
    }
}

static void process_move_to_milk_exit(void)
{
    printf("到达奶浆加注位置\n");
}

// 加注奶浆状态
static void process_fill_milk_enter(void)
{
    printf("进入加注奶浆状态\n");
    process_data.timer = system_get_time_ms();

    // 开始加注奶浆
    if (!milk_dispense_start())
    {
        set_error(ERROR_MILK_DISPENSE_FAILED);
        return;
    }
}

static void process_fill_milk_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 加注完成
    if (elapsed >= process_data.config.milk.fill_time_ms)
    {
        milk_dispense_stop();
        transition_to(PROCESS_MILK_DELAY);
    }
}

static void process_fill_milk_exit(void)
{
    printf("奶浆加注完成\n");
}

// 奶浆完成延时
static void process_milk_delay_enter(void)
{
    printf("进入奶浆完成延时状态\n");
    process_data.timer = system_get_time_ms();
    // 初始化配料处理索引
    process_data.current_jam_idx = 0;
    process_data.current_topping_idx = 0;
}

static void process_milk_delay_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed >= process_data.config.milk.complete_delay_ms)
    {
        // 检查是否有选中的果酱
        if (process_data.selected_jam_count > 0)
        {
            transition_to(PROCESS_MOVE_TO_JAM);
        }
        // 检查是否有选中的顶料
        else if (process_data.selected_topping_count > 0)
        {
            transition_to(PROCESS_MOVE_TO_TOPPING);
        }
        // 没有配料，直接移动到取餐位置
        else
        {
            transition_to(PROCESS_MOVE_TO_DISPENSE);
        }
    }
}

static void process_milk_delay_exit(void)
{
    printf("奶浆延时完成\n");
}

// 移动到果酱位置
static void process_move_to_jam_enter(void)
{
    // 检查索引有效性
    if (process_data.current_jam_idx >= process_data.selected_jam_count)
    {
        set_error(ERROR_JAM_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_jams[process_data.current_jam_idx];
    JamParams *current_jam = &process_data.config.jams[selectid];
    printf("进入移动到果酱%d（类型：%d）位置状态 x:%d z:%d\n",
           process_data.current_jam_idx + 1, current_jam->type,current_jam->add_pos.x_pos,current_jam->add_pos.z_pos);
    process_data.timer = system_get_time_ms();

    // 移动到当前选中果酱的加注位置
    if (!axis_xz_move_to(current_jam->add_pos))
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }
}

static void process_move_to_jam_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 移动超时检查（5秒）
    if (elapsed > 5000)
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }

    // 移动完成，进入添加果酱
    if (!axis_xz_is_moving())
    {
        transition_to(PROCESS_ADD_JAM);
    }
}

static void process_move_to_jam_exit(void)
{
    printf("到达果酱%d加注位置\n", process_data.current_jam_idx + 1);
}

// 添加果酱状态
static void process_add_jam_enter(void)
{
    if (process_data.current_jam_idx >= process_data.selected_jam_count)
    {
        set_error(ERROR_JAM_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_jams[process_data.current_jam_idx];
    JamParams *current_jam = &process_data.config.jams[selectid];
    printf("进入添加果酱%d（类型：%d）状态\n",
           process_data.current_jam_idx + 1, current_jam->type);
    process_data.timer = system_get_time_ms();

    // 开始添加当前选中的果酱
    if (!jam_dispense_start(current_jam->type))
    {
        set_error(ERROR_JAM_DISPENSE_FAILED);
        return;
    }
}

static void process_add_jam_process(void)
{
    if (process_data.current_jam_idx >= process_data.selected_jam_count)
    {
        set_error(ERROR_JAM_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_jams[process_data.current_jam_idx];
    JamParams *current_jam = &process_data.config.jams[selectid];
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 添加完成
    if (elapsed >= current_jam->add_time_ms)
    {
        jam_dispense_stop(current_jam->type);
        // 更新果酱统计
        update_jam_statistics(current_jam->type);
        transition_to(PROCESS_JAM_DELAY);
    }
}

static void process_add_jam_exit(void)
{
    printf("果酱%d添加完成\n", process_data.current_jam_idx + 1);
}

// 果酱完成延时
static void process_jam_delay_enter(void)
{
      uint8_t selectid = process_data.selected_jams[process_data.current_jam_idx];
    JamParams *current_jam = &process_data.config.jams[selectid];
    printf("进入果酱%d完成延时状态 %d ms\n", process_data.current_jam_idx + 1,current_jam->complete_delay_ms);
    process_data.timer = system_get_time_ms();
}

static void process_jam_delay_process(void)
{
    if (process_data.current_jam_idx >= process_data.selected_jam_count)
    {
        set_error(ERROR_JAM_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_jams[process_data.current_jam_idx];
    JamParams *current_jam = &process_data.config.jams[selectid];
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed >= current_jam->complete_delay_ms)
    {
        // 处理下一个选中的果酱
        process_data.current_jam_idx++;
        if (process_data.current_jam_idx < process_data.selected_jam_count)
        {
            transition_to(PROCESS_MOVE_TO_JAM);
        }
        else
        {
            // 所有选中果酱处理完成，检查是否有顶料
            if (process_data.selected_topping_count > 0)
            {
                transition_to(PROCESS_MOVE_TO_TOPPING);
            }
            else
            {
                transition_to(PROCESS_MOVE_TO_DISPENSE);
            }
        }
    }
}

static void process_jam_delay_exit(void)
{
    printf("果酱%d延时完成\n", process_data.current_jam_idx);
}

// 移动到顶料位置
static void process_move_to_topping_enter(void)
{
    if (process_data.current_topping_idx >= process_data.selected_topping_count)
    {
        set_error(ERROR_TOPPING_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_toppings[process_data.current_topping_idx];
    ToppingParams *current_topping = &process_data.config.toppings[selectid];

    printf("进入移动到顶料%d（类型：%d）位置状态 x:%d z:%d\n",
           process_data.current_topping_idx + 1, current_topping->type,current_topping->add_pos.x_pos,current_topping->add_pos.z_pos);
    process_data.timer = system_get_time_ms();

    if (!axis_xz_move_to(current_topping->add_pos))
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }
}

static void process_move_to_topping_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed > 5000)
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }

    if (!axis_xz_is_moving())
    {
        transition_to(PROCESS_ADD_TOPPING);
    }
}

static void process_move_to_topping_exit(void)
{
    printf("到达顶料%d加注位置\n", process_data.current_topping_idx + 1);
}

// 添加顶料状态
static void process_add_topping_enter(void)
{
    if (process_data.current_topping_idx >= process_data.selected_topping_count)
    {
        set_error(ERROR_TOPPING_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_toppings[process_data.current_topping_idx];
    ToppingParams *current_topping = &process_data.config.toppings[selectid];
    printf("进入添加顶料%d（类型：%d）状态\n",
           process_data.current_topping_idx + 1, current_topping->type);
    process_data.timer = system_get_time_ms();

    if (!topping_dispense_start(current_topping->type))
    {
        set_error(ERROR_TOPPING_DISPENSE_FAILED);
        return;
    }
}

static void process_add_topping_process(void)
{
    if (process_data.current_topping_idx >= process_data.selected_topping_count)
    {
        set_error(ERROR_TOPPING_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_toppings[process_data.current_topping_idx];
    ToppingParams *current_topping = &process_data.config.toppings[selectid];
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed >= current_topping->add_time_ms)
    {
        topping_dispense_stop(current_topping->type);
        // 更新顶料统计
        update_topping_statistics(current_topping->type);
        transition_to(PROCESS_TOPPING_DELAY);
    }
}

static void process_add_topping_exit(void)
{
    printf("顶料%d添加完成\n", process_data.current_topping_idx + 1);
}

// 顶料完成延时
static void process_topping_delay_enter(void)
{
     uint8_t selectid = process_data.selected_toppings[process_data.current_topping_idx];
    ToppingParams *current_topping = &process_data.config.toppings[selectid];
    printf("进入顶料%d完成延时状态 %dms\n", process_data.current_topping_idx + 1,current_topping->complete_delay_ms);
    process_data.timer = system_get_time_ms();
}

static void process_topping_delay_process(void)
{
    if (process_data.current_topping_idx >= process_data.selected_topping_count)
    {
        set_error(ERROR_TOPPING_TYPE_INVALID);
        return;
    }

    uint8_t selectid = process_data.selected_toppings[process_data.current_topping_idx];
    ToppingParams *current_topping = &process_data.config.toppings[selectid];
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed >= current_topping->complete_delay_ms)
    {
        process_data.current_topping_idx++;
        if (process_data.current_topping_idx < process_data.selected_topping_count)
        {
            transition_to(PROCESS_MOVE_TO_TOPPING);
        }
        else
        {
            transition_to(PROCESS_MOVE_TO_DISPENSE);
        }
    }
}

static void process_topping_delay_exit(void)
{
    printf("顶料%d延时完成\n", process_data.current_topping_idx);
}

// 移动到取餐位置
static void process_move_to_dispense_enter(void)
{
    printf("进入移动到取餐位置状态\n");
    process_data.timer = system_get_time_ms();

    if (!axis_xz_move_to(process_data.config.dispense_pos))
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }
}

static void process_move_to_dispense_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    if (elapsed > 5000)
    {
        set_error(ERROR_AXIS_MOVE_TIMEOUT);
        return;
    }

    if (!axis_xz_is_moving())
    {
        transition_to(PROCESS_OPEN_DOOR);
    }
}

static void process_move_to_dispense_exit(void)
{
    printf("到达取餐位置\n");
}

// 打开取餐门
static void process_open_door_enter(void)
{
    printf("进入打开取餐门状态\n");
    process_data.timer = system_get_time_ms();

    if (!door_open())
    {
        set_error(ERROR_DOOR_CONTROL_FAILED);
        return;
    }
}

static void process_open_door_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 门打开超时检查（3秒）
    if (elapsed > 3000)
    {
        if (door_is_open())
        {
            transition_to(PROCESS_WAIT_TAKEAWAY);
        }
        else
        {
            set_error(ERROR_DOOR_CONTROL_FAILED);
        }
    }
    else if (door_is_open())
    {
        transition_to(PROCESS_WAIT_TAKEAWAY);
    }
}

static void process_open_door_exit(void)
{
    printf("取餐门已打开\n");
}

// 等待取餐
static void process_wait_takeaway_enter(void)
{
    printf("进入等待取餐状态\n");
    process_data.timer = system_get_time_ms();
}

static void process_wait_takeaway_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 取餐超时检查（30秒）
    if (elapsed > 30000)
    {
        transition_to(PROCESS_CLOSE_DOOR);
    }

    // 检测到取餐完成
    if (takeaway_is_detected())
    {
        transition_to(PROCESS_CLOSE_DOOR);
    }
}

static void process_wait_takeaway_exit(void)
{
    printf("取餐检测完成\n");
}

// 关闭取餐门
static void process_close_door_enter(void)
{
    printf("进入关闭取餐门状态\n");
    process_data.timer = system_get_time_ms();

    if (!door_close())
    {
        set_error(ERROR_DOOR_CONTROL_FAILED);
        return;
    }
}

static void process_close_door_process(void)
{
    uint32_t elapsed = system_get_time_ms() - process_data.timer;

    // 门关闭超时检查（3秒）
    if (elapsed > 3000)
    {
        if (!door_is_open())
        {
            transition_to(PROCESS_COMPLETE);
        }
        else
        {
            set_error(ERROR_DOOR_CONTROL_FAILED);
        }
    }
    else if (!door_is_open())
    {
        transition_to(PROCESS_COMPLETE);
    }
}

static void process_close_door_exit(void)
{
    printf("取餐门已关闭\n");
}

// 制作完成
static void process_complete_enter(void)
{
    printf("进入制作完成状态\n");
    process_data.timer = system_get_time_ms();
    // 更新出杯统计
    update_cup_statistics();
}

static void process_complete_process(void)
{
    // 5秒后返回空闲状态
    if (system_get_time_ms() - process_data.timer > 5000)
    {

        if (process_data.statistics_updated) // 保存统计数据
        {

            save_statistics();
            process_data.statistics_updated = 0;
        }
        transition_to(PROCESS_IDLE);
    }
}

static void process_complete_exit(void)
{
    printf("制作流程完全结束\n");
}

// 错误状态
static void process_error_enter(void)
{
    printf("进入错误状态，错误代码: %d\n", process_data.error_code);
    ice_cream_control_stop_all(); // 停止所有动作
}

static void process_error_process(void)
{
    // 等待错误处理

    if (process_data.statistics_updated) // 保存统计数据
    {

        save_statistics();
        process_data.statistics_updated = 0;
    }
}

static void process_error_exit(void)
{
    printf("错误状态退出\n");
}

// 公共接口实现
void ice_cream_set_config(const ProductionConfig *config)
{
    if (config != NULL)
    {
        process_data.config = *config;
    }
}

bool ice_cream_set_selected_jams(uint8_t jam[], uint8_t count)
{
    if (jam == NULL)
    {
        return false;
    }

    process_data.selected_jam_count = 0;
    for (uint8_t i = 0; i < count; i++)
    {
        if (process_data.selected_jam_count >= MAX_SELECTED_JAMS)
        {
            return false;
        }
        process_data.selected_jams[process_data.selected_jam_count++] = jam[i];
    }
    return true;
}

bool ice_cream_set_selected_topping(uint8_t topping[], uint8_t count)
{
    if (topping == NULL)
    {
        return false;
    }

    process_data.selected_topping_count = 0;
    for (uint8_t i = 0; i < count; i++)
    {
        if (process_data.selected_topping_count >= MAX_SELECTED_TOPPINGS)
        {
            return false;
        }
        process_data.selected_toppings[process_data.selected_topping_count++] = topping[i];
    }
    return true;
}

/**
 * @brief 清空已选择的配料列表
 */
void ice_cream_clear_selected_ingredients(void)
{
    process_data.selected_jam_count = 0;
    process_data.selected_topping_count = 0;
}

bool ice_cream_start_process(void)
{
    if (state_machine_get_current(&process_data.fsm) == PROCESS_IDLE)
    {
        transition_to(PROCESS_INIT);
        return true;
    }
    return false;
}

void ice_cream_stop_process(void)
{
    ice_cream_control_stop_all();
    transition_to(PROCESS_IDLE);
}

void ice_cream_process_handler(void)
{
    state_machine_process(&process_data.fsm);
}

ProcessState ice_cream_get_current_state(void)
{
    return (ProcessState)state_machine_get_current(&process_data.fsm);
}

ErrorCode ice_cream_get_error_code(void)
{
    return process_data.error_code;
}

void ice_cream_clear_error(void)
{
    process_data.error_code = ERROR_NONE;
    transition_to(PROCESS_IDLE);
}

// 统计信息获取接口
uint32_t ice_cream_get_total_cups(void)
{
    return process_data.stats.total_cups.count;
}

uint32_t ice_cream_get_jam_count(uint8_t jam_type)
{
    if (jam_type < 3)
    {
        return process_data.stats.jam[jam_type].count;
    }
    return 0;
}

uint32_t ice_cream_get_topping_count(uint8_t topping_type)
{
    if (topping_type < 3)
    {
        return process_data.stats.topping[topping_type].count;
    }
    return 0;
}

// 新增：保存统计数据到存储设备
static bool save_statistics(void)
{
    // 实际应用中应根据硬件情况实现此函数
    // 可能需要使用文件系统、EEPROM或其他存储方式

    return true;
}
// 新增：从存储设备加载统计数据
static bool load_statistics(void)
{

    // 读取统计数据
    Statistics loaded_stats = {0};

    process_data.stats = loaded_stats;

    return false;
}
void ice_cream_process_init(void)
{
    memset(&process_data, 0, sizeof(ice_cream_process_data_t));

    // 初始化状态机
    state_machine_init(&process_data.fsm, process_states,
                       PROCESS_STATE_COUNT, PROCESS_IDLE);
    ice_cream_config_init();
    ice_control_init();
    load_statistics();
}

ice_cream_process_data_t *ice_icream_process_data_get()
{
    return &process_data;
}

/*bool ice_cream_set_selected_jams(uint8_t jam[], uint8_t count);
bool ice_cream_set_selected_topping(uint8_t topping[], uint8_t count);
ice_cream_start_process

*/
// 编写可以msh shell输入参数的函数选择指定果酱和顶料 自动制作冰淇淋的函数测试命令

/**
 * 冰淇淋制作测试命令
 * 用法: make_ice [果酱ID列表] [顶料ID列表]
 * 示例: make_ice 1,3 2  (选择草莓酱、香草酱，搭配饼干碎)
 */
void make_ice_cream(int argc, char **argv)
{
    uint8_t jams[3] = {0};     // 最多3种果酱
    uint8_t toppings[3] = {0}; // 最多3种顶料
    uint8_t jam_count = 0;
    uint8_t topping_count = 0;
    char *token;
    int val;
    for (int i = 1; i < argc; i++)
    {
        printf("arg %d: %s\n", i, argv[i]);
    }
    // 检查参数数量
    if (argc != 3)
    {
        printf("命令格式错误！正确用法:\n");
        printf("make_ice [果酱列表] [顶料列表]\n");
        printf("果酱选项: 1-草莓酱 2-香蕉酱 3-香草酱\n");
        printf("顶料选项: 1-坚果碎 2-饼干碎 3-巧克力碎\n");
        printf("示例: make_ice 1,3 2\n");
        return;
    }

    // 解析果酱参数
    token = strtok(argv[1], ",");
    while (token != NULL && jam_count < 3)
    {
        val = atoi(token);
        if (val < 1 || val > 3)
        {
            printf("无效果酱ID: %d（仅支持1-3）\n", val);
            return;
        }
        jams[jam_count++] = val-1;
        token = strtok(NULL, ",");
    }

    // 解析顶料参数
    token = strtok(argv[2], ",");
    while (token != NULL && topping_count < 3)
    {
        val = atoi(token);
        if (val < 1 || val > 3)
        {
            printf("无效顶料ID: %d（仅支持1-3）\n", val);
            return;
        }
        toppings[topping_count++] = val-1;
        token = strtok(NULL, ",");
    }

    // 验证选择数量
    if (jam_count == 0 || topping_count == 0)
    {
        printf("请至少选择一种果酱和一种顶料\n");
        return;
    }
    // 打印出选择顶料和果酱

    printf("已选择以下原料:\n");
    for (int i = 0; i < jam_count; i++)
    {
        printf("果酱: %d\n", jams[i]+1);
    }
    for (int i = 0; i < topping_count; i++)
    {
        printf("顶料: %d\n", toppings[i]+1);
    }
    // 设置选择的原料
    if (!ice_cream_set_selected_jams(jams, jam_count))
    {
        printf("果酱设置失败\n");
        return;
    }

    if (!ice_cream_set_selected_topping(toppings, topping_count))
    {
        printf("顶料设置失败\n");
        return;
    }

    // 启动制作流程
    printf("开始制作冰淇淋...\n");
    ice_cream_clear_error();
    ice_cream_start_process();
    printf("冰淇淋制作完成！\n");
}